package com.hera.process.config.rest.delegate.impl;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.client.RestTemplate;

import com.hera.base.domain.WrapperJSON;
import com.hera.base.rest.delegate.BaseDelegate;
import com.hera.base.util.FiltroDTO;
import com.hera.process.config.rest.delegate.WorkflowDelegate;
import com.hera.process.form.domain.FormField;
import com.hera.process.workflow.domain.ProcInstancHistory;
import com.hera.process.workflow.domain.ProcInstancNote;
import com.hera.process.workflow.domain.Process;
import com.hera.process.workflow.domain.ProcessCategory;
import com.hera.process.workflow.domain.ProcessGroup;
import com.hera.process.workflow.domain.ProcessGroupUser;
import com.hera.process.workflow.domain.ProcessInstance;
import com.hera.process.workflow.domain.ProcessSupervisor;
import com.hera.process.workflow.domain.Stage;
import com.hera.process.workflow.domain.StageRollup;
import com.hera.process.workflow.domain.StageUser;
import com.hera.process.workflow.domain.Swimlane;
import com.hera.process.workflow.domain.TaskInstanceCache;
import com.hera.process.workflow.domain.TaskUser;

@Service
public class WorkflowDelegateImpl extends BaseDelegate implements WorkflowDelegate {

	@Autowired
	private RestTemplate restTemplate;
	
	@Value("${url.contexto.workflow}")
	private String urlController;
	
	@Value("${url.base}")
	private String urlBase;
	
	
	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// PROCESSCATEGORY ///////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/

	@Override
	public List<ProcessCategory> findAllProcessCategories(FiltroDTO filtroDTO) {
		
        
        return postForObject(urlBase+urlController+"processcategory/list", filtroDTO,
        		new ParameterizedTypeReference<WrapperJSON<List<ProcessCategory>>>() {});
	}

	@Override
	public ProcessCategory createProcessCategory(ProcessCategory procategpry) {
		 return postForObject(urlBase+urlController+"processcategory/save", procategpry,
	        		new ParameterizedTypeReference<WrapperJSON<ProcessCategory>>() {});
	}

	@Override
	public ProcessCategory updateProcessCategory(ProcessCategory procategory) {
		return postForObject(urlBase+urlController+"processcategory/update", procategory,
        		new ParameterizedTypeReference<WrapperJSON<ProcessCategory>>() {});
	}

	@Override
	public void deleteProCategory(ProcessCategory procategory) {
		
		 postForObject(urlBase+urlController+"processcategory/delete", procategory,
	        		new ParameterizedTypeReference<WrapperJSON<ProcessCategory>>() {});
	}
	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// PROCESS ///////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/
	
	
	@Override
	public List<Process> findAllProcesses(FiltroDTO filtroDTO) {        
        return postForObject(urlBase+urlController+"process/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<Process>>>() {});
	}

	@Override
	public Process createProcess(Process process) {
		return postForObject(urlBase+urlController+"process/save", process, 
        		new ParameterizedTypeReference<WrapperJSON<Process>>() {});		
	}

	@Override
	public Process updateProcess(Process process) {	
		return postForObject(urlBase+urlController+"process/update", process, 
		new ParameterizedTypeReference<WrapperJSON<Process>>() {});		
	}


	@Override
	public void deleteProcess(Process process) {
		postForObject(urlBase+urlController+"process/delete", process, 
        		new ParameterizedTypeReference<WrapperJSON<Process>>() {});
	}
	
	@Override
	public void publicarProceso(Process process) {		
		postForObject(urlBase+urlController+"process/publicarProceso", process, 
        		new ParameterizedTypeReference<WrapperJSON<Process>>() {});
	}
	
	@Override
	public boolean validarProceso(Process process) {		
		return postForObject(urlBase+urlController+"process/validarProceso", process, 
        		new ParameterizedTypeReference<WrapperJSON<Boolean>>() {});
	}
		
	@Override
	public List<FormField> findAllFormFieldInProcess(@RequestBody Process process) {
		return postForObject(urlBase+urlController+"process/findAllFormFieldInProcess", process, 
	        		new ParameterizedTypeReference<WrapperJSON<List<FormField>>>() {});
	}
	
	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// PROCESGROUP ///////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/
	
	@Override
	public List<ProcessGroup> findAllProcessGroups(FiltroDTO filtroDTO) {

        return postForObject(urlBase+urlController+"processgroup/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<ProcessGroup>>>() {});
	}

	@Override
	public ProcessGroup createProcessGroup(ProcessGroup processgroup) {
		
		return postForObject(urlBase+urlController+"processgroup/save", processgroup, 
		        		new ParameterizedTypeReference<WrapperJSON<ProcessGroup>>() {});
	}

	@Override
	public ProcessGroup updateProcessGroup(ProcessGroup processgroup) {
		return postForObject(urlBase+urlController+"processgroup/update", processgroup, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessGroup>>() {});
	}

	@Override
	public void deleteProcessgroup(ProcessGroup processgroup) {
		 postForObject(urlBase+urlController+"processgroup/delete", processgroup, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessGroup>>() {});
		
	
	}
	
	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// PROCESSGROUPUSER ///////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/
	
	@Override
	public List<ProcessGroupUser> findAllProcessGroupUsers(FiltroDTO filtroDTO) {
        return postForObject(urlBase+urlController+"processgroupuser/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<ProcessGroupUser>>>() {});
	}

	@Override
	public ProcessGroupUser createProcessGroupUser(ProcessGroupUser progrouser) {
		return postForObject(urlBase+urlController+"processgroupuser/save", progrouser, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessGroupUser>>() {});
		
	}

	@Override
	public ProcessGroupUser updateProcessGroupUser(ProcessGroupUser progrouser) {
		return postForObject(urlBase+urlController+"processgroupuser/update", progrouser, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessGroupUser>>() {});
	
	}

	@Override
	public void deleteProcessGroupUser(ProcessGroupUser progrouser) {
		postForObject(urlBase+urlController+"processgroupuser/delete", progrouser, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessGroupUser>>() {});
	}
	
	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// PROCESS INSTANCE /////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/
	
	@Override
	public List<ProcessInstance> findAllProcessInstances(FiltroDTO filtroDTO) {        
        return postForObject(urlBase+urlController+"processinstance/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<ProcessInstance>>>() {});
	}

	@Override
	public ProcessInstance createProcessInstance(ProcessInstance proinstance) {
		 return postForObject(urlBase+urlController+"processinstance/save", proinstance, 
	        		new ParameterizedTypeReference<WrapperJSON<ProcessInstance>>() {});
	}

	@Override
	public ProcessInstance updateProcessInstance(ProcessInstance proinstance) {
		return postForObject(urlBase+urlController+"processinstance/update", proinstance, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessInstance>>() {});
	
	}

	@Override
	public void deleteProcessInstance(ProcessInstance proinstance) {
		postForObject(urlBase+urlController+"processinstance/delete", proinstance, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessInstance>>() {});
	}
	
	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// PROCESS SUPERVISOR /////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/
	
	@Override
	public List<ProcessSupervisor> findAllProcessSupervisors(FiltroDTO filtroDTO) {
        return postForObject(urlBase+urlController+"processsupervisor/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<ProcessSupervisor>>>() {});
	}

	@Override
	public ProcessSupervisor createProcessSupervisor(ProcessSupervisor prosuper) {
		return postForObject(urlBase+urlController+"processsupervisor/save", prosuper, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessSupervisor>>() {});
	}

	@Override
	public ProcessSupervisor updateProcessSupervisor(ProcessSupervisor prosuper) {
		return postForObject(urlBase+urlController+"processsupervisor/update", prosuper, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessSupervisor>>() {});
	}

	@Override
	public void deleteProcessSupervisor(ProcessSupervisor prosuper) {
		postForObject(urlBase+urlController+"processsupervisor/delete", prosuper, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessSupervisor>>() {});
	}
	
	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// PROCESSINSTANCE HISTORY /////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/

	@Override
	public List<ProcInstancHistory> findAllProceInstancHistories(FiltroDTO filtroDTO) {
		 return postForObject(urlBase+urlController+"procInstanchistory/list", filtroDTO, 
	        		new ParameterizedTypeReference<WrapperJSON<List<ProcInstancHistory>>>() {});
		
	}

	@Override
	public ProcInstancHistory createProceHistory(ProcInstancHistory prohisto) {
		return postForObject(urlBase+urlController+"procInstanchistory/save", prohisto, 
        		new ParameterizedTypeReference<WrapperJSON<ProcInstancHistory>>() {});
	}

	@Override
	public ProcInstancHistory updateProcesHistory(ProcInstancHistory prohisto) {
		return postForObject(urlBase+urlController+"procInstanchistory/update", prohisto, 
        		new ParameterizedTypeReference<WrapperJSON<ProcInstancHistory>>() {});
	}

	@Override
	public void deleteProInstanceHistory(ProcInstancHistory prohisto) {
		postForObject(urlBase+urlController+"procInstanchistory/delete", prohisto, 
        		new ParameterizedTypeReference<WrapperJSON<ProcInstancHistory>>() {});
	}

	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// PROCESSINSTANCE NOTES /////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/
	
	@Override
	public List<ProcInstancNote> findAllProceInstancNotes(FiltroDTO filtroDTO) {
        return postForObject(urlBase+urlController+"procintancenote/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<ProcInstancNote>>>() {});
	}

	@Override
	public ProcInstancNote createProcInstancNote(ProcInstancNote pronote) {
		 return postForObject(urlBase+urlController+"procintancenote/save", pronote, 
	        		new ParameterizedTypeReference<WrapperJSON<ProcInstancNote>>() {});
	}

	@Override
	public ProcInstancNote updateProcInstancNote(ProcInstancNote pronote) {
		 return postForObject(urlBase+urlController+"procintancenote/update", pronote, 
	        		new ParameterizedTypeReference<WrapperJSON<ProcInstancNote>>() {});
	}

	@Override
	public void deleteProcInstancNote(ProcInstancNote pronote) {
		 postForObject(urlBase+urlController+"procintancenote/", pronote, 
	        		new ParameterizedTypeReference<WrapperJSON<ProcInstancNote>>() {});
	}
	
	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// STAGES ///////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/
	
	@Override
	public List<Stage> findAllStages(FiltroDTO filtroDTO) {
        return postForObject(urlBase+urlController+"stage/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<Stage>>>() {});
	}

	@Override
	public Stage createStage(Stage stage) {
		return postForObject(urlBase+urlController+"stage/save", stage, 
        		new ParameterizedTypeReference<WrapperJSON<Stage>>() {});
	}

	@Override
	public Stage updatedStage(Stage stage) {
		return postForObject(urlBase+urlController+"stage/update", stage, 
        		new ParameterizedTypeReference<WrapperJSON<Stage>>() {});
	}

	@Override
	public void deleteStage(Stage stage) {
		postForObject(urlBase+urlController+"stage/delete", stage, 
        		new ParameterizedTypeReference<WrapperJSON<Stage>>() {});
	}
	
	@Override
	public List<Stage> findStageByProcessId(Stage stage) {
		// TODO Auto-generated method stub
		return postForObject(urlBase+urlController+"stage/findStageByProcessId", stage, 
        		new ParameterizedTypeReference<WrapperJSON<List<Stage>>>() {});
	}
	@Override
	public List<Stage> findStageByProcessIdandTypeId(Stage stage) {
		return postForObject(urlBase+urlController+"stage/findStageByProcessIdandTypeId", stage, 
        		new ParameterizedTypeReference<WrapperJSON<List<Stage>>>() {});
	}

	
	@Override
	public List<Stage> findStageByProcessAndIdDiagram(Stage stage){
		return postForObject(urlBase+urlController+"stage/findStageByProcessAndIdDiagram", stage, 
        		new ParameterizedTypeReference<WrapperJSON<List<Stage>>>() {});
	}
	
	@Override
	public ProcessInstance createInstanceProcess(Map<String, Object> entity){
		return postForObject(urlBase+urlController+"stage/createProcessInstance", entity, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessInstance>>() {});
	}
	
	@Override
	public ProcessInstance udpateInstanceProcess(Map<String, Object> entity){
		return postForObject(urlBase+urlController+"stage/updateProcessInstance", entity, 
        		new ParameterizedTypeReference<WrapperJSON<ProcessInstance>>() {});
	}
	
	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// STAGEROLLUPS ///////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/

	@Override
	public List<StageRollup> findAllStageRollups(FiltroDTO filtroDTO) {
		
		/*StageRollup[] list = restTemplate.postForObject(urlBase+urlController+"stagerollup/list", filtroDTO, StageRollup[].class);
        return Arrays.asList(list);*/
		return postForObject(urlBase+urlController+"stagerollup/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<StageRollup>>>() {});
	}

	@Override
	public StageRollup createStageRollup(StageRollup stagerollup) {
		
		//return restTemplate.postForObject(urlBase+urlController+"stagerollup/save", stagerollup, StageRollup.class);
		return postForObject(urlBase+urlController+"stagerollup/save", stagerollup, 
        		new ParameterizedTypeReference<WrapperJSON<StageRollup>>() {});
	}

	@Override
	public StageRollup updatedStageRollup(StageRollup stagerollup) {
	
		
		return postForObject(urlBase+urlController+"stagerollup/update", stagerollup, 
        		new ParameterizedTypeReference<WrapperJSON<StageRollup>>() {});
	}

	@Override
	public void deleteStageRollup(StageRollup stagerollup) {
		
		postForObject(urlBase+urlController+"stagerollup/delete", stagerollup, 
        		new ParameterizedTypeReference<WrapperJSON<StageRollup>>() {});
	}
	
	@Override
	public List<StageRollup> findStageRollupByProcessId(Long idProcess) {
		// TODO Auto-generated method stub
		return postForObject(urlBase+urlController+"stagerollup/findStageRollupByProcessId", idProcess, 
        		new ParameterizedTypeReference<WrapperJSON<List<StageRollup>>>() {});
	}
	
	@Override
	public List<StageRollup> findStageRollupByProcessAndIdDiagram(StageRollup stagerollup) {
		// TODO Auto-generated method stub
		return postForObject(urlBase+urlController+"stagerollup/findStageRollupByProcessAndIdDiagram", stagerollup, 
        		new ParameterizedTypeReference<WrapperJSON<List<StageRollup>>>() {});
	}


	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// STAGE USER ///////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/

	@Override
	public List<StageUser> findAllStageUsers(FiltroDTO filtroDTO) {		
		
        return postForObject(urlBase+urlController+"stageuser/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<StageUser>>>() {});
	}
	
	@Override
	public StageUser createStageUser(StageUser stageuser) {
		
		return postForObject(urlBase+urlController+"stageuser/save", stageuser, 
        		new ParameterizedTypeReference<WrapperJSON<StageUser>>() {});
	}

	@Override
	public StageUser updatedStageUser(StageUser stageuser) {
	
		return postForObject(urlBase+urlController+"stageuser/update", stageuser, 
        		new ParameterizedTypeReference<WrapperJSON<StageUser>>() {});
	}

	@Override
	public void deleteStageUser(StageUser stageuser) {
	
		postForObject(urlBase+urlController+"stageuser/delete", stageuser, 
        		new ParameterizedTypeReference<WrapperJSON<StageUser>>() {});
	}
	
	@Override
	public List<StageUser> findStageUserByStage(Stage stage) {
		return postForObject(urlBase+urlController+"stageuserbystage/list", stage,
        		new ParameterizedTypeReference<WrapperJSON<List<StageUser>>>() {});
	}
	
	

	
	/*
	///////////////////////////////////////////////////////////////////////////////////
	 /////////////////////////////// SWIMLANES ///////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/

	@Override
	public List<Swimlane> findAllSwimlanes(FiltroDTO filtroDTO) {
				
        return postForObject(urlBase+urlController+"swimlane/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<Swimlane>>>() {});
	}

	@Override
	public Swimlane createSwimlane(Swimlane swimlane) {
				
		return postForObject(urlBase+urlController+"swimlane/save", swimlane, 
        		new ParameterizedTypeReference<WrapperJSON<Swimlane>>() {});
	}

	@Override
	public Swimlane updatedSwimlane(Swimlane swimlane) {
				
		return postForObject(urlBase+urlController+"swimlane/update", swimlane, 
        		new ParameterizedTypeReference<WrapperJSON<Swimlane>>() {});
	}

	@Override
	public void deleteSwimlane(Swimlane swimlane) {
				
		postForObject(urlBase+urlController+"swimlane/delete", swimlane, 
        		new ParameterizedTypeReference<WrapperJSON<Swimlane>>() {});
	}
	
	@Override
	public List<Swimlane> findSwimlaneByProcessId(Long idProcess) {
		// TODO Auto-generated method stub
		return postForObject(urlBase+urlController+"swimlane/findSwimlaneByProcessId", idProcess, 
        		new ParameterizedTypeReference<WrapperJSON<List<Swimlane>>>() {});
	}
	
	

	/*
	///////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////// TASK INSTANCE CACHE //////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/
	
	@Override
	public List<TaskInstanceCache> findAllTaskInstanceCaches(FiltroDTO filtroDTO) {
        
        return postForObject(urlBase+urlController+"taskintcache/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<TaskInstanceCache>>>() {});
	}

	@Override
	public TaskInstanceCache createTaskInstanceCache(TaskInstanceCache taskcache) {
	
		 return postForObject(urlBase+urlController+"taskintcache/save", taskcache, 
	        		new ParameterizedTypeReference<WrapperJSON<TaskInstanceCache>>() {});
	}

	@Override
	public TaskInstanceCache updatedTaskInstanceCache(TaskInstanceCache taskcache) {
	
		 return postForObject(urlBase+urlController+"taskintcache/update", taskcache, 
	        		new ParameterizedTypeReference<WrapperJSON<TaskInstanceCache>>() {});
	}

	@Override
	public void deleteTaskInstanceCache(TaskInstanceCache taskcache) {
		
		postForObject(urlBase+urlController+"taskintcache/delete", taskcache, 
        		new ParameterizedTypeReference<WrapperJSON<TaskInstanceCache>>() {});
	}
	
	/*
	///////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////// TASK USER	///////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	*/

	@Override
	public List<TaskUser> findBandejaUsuario(Long codigoJefe) {
		
		return postForObject(urlBase+urlController+"taskuser/findBandejaUsuario", codigoJefe, 
        		new ParameterizedTypeReference<WrapperJSON<List<TaskUser>>>() {});
	}
	@Override
	public List<TaskUser> findAllTaskUsers(FiltroDTO filtroDTO) {
        return postForObject(urlBase+urlController+"taskuser/list", filtroDTO, 
        		new ParameterizedTypeReference<WrapperJSON<List<TaskUser>>>() {});
	}

	@Override
	public TaskUser createTaskUser(TaskUser taskuser) {
		
		 return postForObject(urlBase+urlController+"taskuser/save", taskuser, 
	        		new ParameterizedTypeReference<WrapperJSON<TaskUser>>() {});
	}

	@Override
	public TaskUser updatedTaskUser(TaskUser taskuser) {
		return postForObject(urlBase+urlController+"taskuser/update", taskuser, 
        		new ParameterizedTypeReference<WrapperJSON<TaskUser>>() {});
	}

	@Override
	public void deleteTaskUser(TaskUser taskuser) {
		
		postForObject(urlBase+urlController+"taskuser/delete", taskuser, 
        		new ParameterizedTypeReference<WrapperJSON<TaskUser>>() {});
		
	}
	
	

}
